home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / DEMOS / SMOOTH / GLTX.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  5.0 KB  |  241 lines

  1. /*
  2.  *  Simple SGI .rgb (IRIS RGB) image file reader ripped off from
  3.  *  texture.c (written by David Blythe).  See the SIGGRAPH '96
  4.  *  Advanced OpenGL course notes.
  5.  */
  6.  
  7.  
  8. /* includes */
  9. #include <stdio.h>
  10. #include <stdlib.h> 
  11. #include <string.h>
  12. #include <assert.h>
  13. #include "gltx.h"
  14.  
  15.  
  16. /* private typedefs */
  17. typedef struct _rawImageRec {
  18.     unsigned short imagic;
  19.     unsigned short type;
  20.     unsigned short dim;
  21.     unsigned short sizeX, sizeY, sizeZ;
  22.     unsigned long min, max;
  23.     unsigned long wasteBytes;
  24.     char name[80];
  25.     unsigned long colorMap;
  26.     FILE *file;
  27.     unsigned char *tmp, *tmpR, *tmpG, *tmpB;
  28.     unsigned long rleEnd;
  29.     GLuint *rowStart;
  30.     GLint *rowSize;
  31. } rawImageRec;
  32.  
  33.  
  34. /* private functions */
  35. static void ConvertShort(unsigned short *array, unsigned int length)
  36. {
  37.     unsigned short b1, b2;
  38.     unsigned char *ptr;
  39.  
  40.     ptr = (unsigned char *)array;
  41.     while (length--) {
  42.     b1 = *ptr++;
  43.     b2 = *ptr++;
  44.     *array++ = (b1 << 8) | (b2);
  45.     }
  46. }
  47.  
  48. static void ConvertLong(GLuint *array, unsigned int length)
  49. {
  50.     unsigned long b1, b2, b3, b4;
  51.     unsigned char *ptr;
  52.  
  53.     ptr = (unsigned char *)array;
  54.     while (length--) {
  55.     b1 = *ptr++;
  56.     b2 = *ptr++;
  57.     b3 = *ptr++;
  58.     b4 = *ptr++;
  59.     *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
  60.     }
  61. }
  62.  
  63. static rawImageRec *RawImageOpen(char *fileName)
  64. {
  65.     union {
  66.     int testWord;
  67.     char testByte[4];
  68.     } endianTest;
  69.     rawImageRec *raw;
  70.     GLenum swapFlag;
  71.     int x;
  72.  
  73.     endianTest.testWord = 1;
  74.     if (endianTest.testByte[0] == 1) {
  75.     swapFlag = GL_TRUE;
  76.     } else {
  77.     swapFlag = GL_FALSE;
  78.     }
  79.  
  80.     raw = (rawImageRec *)malloc(sizeof(rawImageRec));
  81.     if (raw == NULL) {
  82.     return NULL;
  83.     }
  84.     if ((raw->file = fopen(fileName, "rb")) == NULL) {
  85.     return NULL;
  86.     }
  87.  
  88.     fread(raw, 1, 12, raw->file);
  89.  
  90.     if (swapFlag) {
  91.     ConvertShort(&raw->imagic, 6);
  92.     }
  93.  
  94.     raw->tmp = (unsigned char *)malloc(raw->sizeX*256);
  95.     raw->tmpR = (unsigned char *)malloc(raw->sizeX*256);
  96.     raw->tmpG = (unsigned char *)malloc(raw->sizeX*256);
  97.     raw->tmpB = (unsigned char *)malloc(raw->sizeX*256);
  98.     if (raw->tmp == NULL || raw->tmpR == NULL || raw->tmpG == NULL ||
  99.     raw->tmpB == NULL) {
  100.     return NULL;
  101.     }
  102.  
  103.     if ((raw->type & 0xFF00) == 0x0100) {
  104.     x = raw->sizeY * raw->sizeZ * sizeof(GLuint);
  105.     raw->rowStart = (GLuint *)malloc(x);
  106.     raw->rowSize = (GLint *)malloc(x);
  107.     if (raw->rowStart == NULL || raw->rowSize == NULL) {
  108.         return NULL;
  109.     }
  110.     raw->rleEnd = 512 + (2 * x);
  111.     fseek(raw->file, 512, SEEK_SET);
  112.     fread(raw->rowStart, 1, x, raw->file);
  113.     fread(raw->rowSize, 1, x, raw->file);
  114.     if (swapFlag) {
  115.         ConvertLong(raw->rowStart, x/sizeof(GLuint));
  116.         ConvertLong((GLuint *)raw->rowSize, x/sizeof(GLint));
  117.     }
  118.     }
  119.     return raw;
  120. }
  121.  
  122. static void RawImageClose(rawImageRec *raw)
  123. {
  124.  
  125.     fclose(raw->file);
  126.     free(raw->tmp);
  127.     free(raw->tmpR);
  128.     free(raw->tmpG);
  129.     free(raw->tmpB);
  130.  
  131.     free(raw);
  132. }
  133.  
  134. static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z)
  135. {
  136.   unsigned char *iPtr, *oPtr, pixel;
  137.   int count;
  138.  
  139.   if ((raw->type & 0xFF00) == 0x0100) {
  140.     fseek(raw->file, (long) raw->rowStart[y+z*raw->sizeY], SEEK_SET);
  141.     fread(raw->tmp, 1, (unsigned int)raw->rowSize[y+z*raw->sizeY],
  142.       raw->file);
  143.  
  144.     iPtr = raw->tmp;
  145.     oPtr = buf;
  146.     for (;;) {
  147.       pixel = *iPtr++;
  148.       count = (int)(pixel & 0x7F);
  149.       if (!count) {
  150.     return;
  151.       }
  152.       if (pixel & 0x80) {
  153.     while (count--) {
  154.       *oPtr++ = *iPtr++;
  155.     }
  156.       } else {
  157.     pixel = *iPtr++;
  158.     while (count--) {
  159.       *oPtr++ = pixel;
  160.     }
  161.       }
  162.     }
  163.   } else {
  164.     fseek(raw->file, 512+(y*raw->sizeX)+(z*raw->sizeX*raw->sizeY),
  165.       SEEK_SET);
  166.     fread(buf, 1, raw->sizeX, raw->file);
  167.   }
  168. }
  169.  
  170. static void
  171. RawImageGetData(rawImageRec *raw, GLTXimage *image)
  172. {
  173.   unsigned char *ptr;
  174.   int i, j;
  175.  
  176.   image->data = (unsigned char *)malloc((raw->sizeX+1)*(raw->sizeY+1)*4);
  177.   if (image->data == NULL) {
  178.     return;
  179.   }
  180.  
  181.   ptr = image->data;
  182.   for (i = 0; i < raw->sizeY; i++) {
  183.     RawImageGetRow(raw, raw->tmpR, i, 0);
  184.     RawImageGetRow(raw, raw->tmpG, i, 1);
  185.     RawImageGetRow(raw, raw->tmpB, i, 2);
  186.     for (j = 0; j < raw->sizeX; j++) {
  187.       *ptr++ = *(raw->tmpR + j);
  188.       *ptr++ = *(raw->tmpG + j);
  189.       *ptr++ = *(raw->tmpB + j);
  190.     }
  191.   }
  192. }
  193.  
  194.  
  195.  
  196. /* public functions */
  197.  
  198. /* gltxDelete: Deletes a texture image
  199.  * 
  200.  * image - properly initialized GLTXimage structure
  201.  */
  202. void
  203. gltxDelete(GLTXimage* image)
  204. {
  205.   assert(image);
  206.  
  207.   free(image->data);
  208.   free(image);
  209. }
  210.  
  211. /* gltxReadRGB: Reads and returns data from an IRIS RGB image file.
  212.  *
  213.  * filename - name of the IRIS RGB file to read data from
  214.  */
  215. GLTXimage*
  216. gltxReadRGB(char *filename)
  217. {
  218.   rawImageRec *raw;
  219.   GLTXimage* image;
  220.  
  221.   raw = RawImageOpen(filename);
  222.   if(!raw) {
  223.     fprintf(stderr, "gltxReadRGB() failed: can't open image file \"%s\".\n",
  224.         filename);
  225.     return NULL;
  226.   }
  227.   image = (GLTXimage*)malloc(sizeof(GLTXimage));
  228.   if (image == NULL) {
  229.     fprintf(stderr, "gltxReadRGB() failed: insufficient memory.\n");
  230.     return NULL;
  231.   }
  232.  
  233.   image->width = raw->sizeX;
  234.   image->height = raw->sizeY;
  235.   image->components = raw->sizeZ;
  236.   RawImageGetData(raw, image);
  237.   RawImageClose(raw);
  238.  
  239.   return image;
  240. }
  241.